#pragma once
#include <string>
#include <map>
#include <stack>
#include "TransformationParser.h"
#include "ComponentParser.h"
#include "PrimitiveParser.h"
#include <iostream>
#include "RectangleParser.h"
#include "TriangleParser.h"
#include "SphereParser.h"
#include "TorusParser.h"
#include "CylinderParser.h"
#include "MaterialParser.h"
#include "TextureParser.h"
#include "ViewParser.h"
#include "PerspectiveParser.h"
#include "OrthoParser.h"
#include "LightParser.h"
#include "OmniLightParser.h"
#include "SpotLightParser.h"
#include "RGBpixmap.h"
#include "tinyxml.h"

#include <math.h>

#include <gl\glui.h>

using std::string;
using std::map;
using std::cout;
using std::cin;
using std::endl;

struct Illumination{
	int doublesided;
	int local;
	float ambient[4];
	float background[4];
};

class Parser
{
public:
	map<string, vector<TransformationParser> > transformations;
	map<string, ComponentParser> components;
	map<string, PrimitiveParser*> primitives;
	map<string, MaterialParser> materials;
	map<char, ComponentParser*> changing_materials;
	map<string, TextureParser> textures;
	
	//a chave string representa o nome do ficheiro e nao o id da textura
	//texturas diferentes podem ser do mesmo ficheiro
	//nao ha necessidade de carregar duas vezes a mesma textura
	map<string, int> textures_id;
	int n_textures;
	RGBpixmap pixmap;

	string root_id;
	ComponentParser* root;

	float axis_length;

	stack< MaterialParser* > materials_stack;
	stack< TextureParser* > textures_stack;
	
	Illumination illumination;

	vector<ViewParser*> views;
	int current_view;

	vector<LightParser* > lights;

	Parser(void);
	~Parser(void);

	void loadIllumination(TiXmlElement* illuminationElem);
	void loadViews(TiXmlElement* viewsElem);
	void loadLights(TiXmlElement* lightsElem);

	void loadTransformations(TiXmlElement* transformationsElem);
	void loadMaterials(TiXmlElement* materialsElem);
	void loadTextures(TiXmlElement* texturesElem);
	void loadPrimitives(TiXmlElement* primitivesElem);
	void loadComponents(TiXmlElement* componentsElem);
	void loadFile(string filename);

	void setComponentsTransformationMatrix();
	void setComponentsChildren();
	void setMaterials();
	void setTextures();

	void showContents();

	void drawScene();

	void processComponent(ComponentParser* comp);
	void processPrimitive(PrimitiveParser* prim);

	void changeView(int i){ current_view = i;}
};

